#pragma once

#include <winsock2.h>

#include "mysql.h"

#include "Lock.h"

#include <list>

#include "ThreadPool.h"

//#pragma comment(lib,"ws2_32.lib")

using namespace std;
using namespace YYMYSQL;

#ifdef EXPORTDLL
	#define _DLL _declspec(dllexport)
#else
	#define _DLL _declspec(dllimport)
#endif

class QueryBuffer
{
public:
	void push(char*query)
	{
		CAutoLock lock(&_lock);

		_buffer.push_back(query);
	}

	char * get()
	{
		CAutoLock lock(&_lock);

		char * tmp = _buffer.front();

		_buffer.pop_front();

		return tmp;
	}

protected:
private:
	list<char*> _buffer;
	YYMYSQL::CLock _lock;
};

class CYYMySqlCon//:public CLock,public QueryBuffer
{
public:
	MYSQL* _sql;
};

class CYYJob:public IJobDesc//,public CLock
{
public:
	CYYMySqlCon * _con;
	char _query[256];
protected:
private:
};

class CYYMysql;

class _DLL CYYWorker:public IWorker
{
public:
	CYYWorker(CYYMysql*sql)
	{
		_mysql = sql;
	}
	void ProcessJob(IJobDesc* pJob);
private:
	CYYMysql * _mysql;
};

typedef list<CYYMySqlCon*>YYMySqlConList;
typedef YYMySqlConList::iterator YYMySqlConListIt;

typedef list<CYYJob*>YYJobList;
typedef YYJobList::iterator YYJobListIt;


class CMySqlResult
{
public:
	char _name[32];
	char _data[128];
	BYTE _fields;

	CMySqlResult()
	{
		memset(this,0,sizeof(CMySqlResult));
	}
protected:
private:
};

typedef list<CMySqlResult> MySqlResultList;
typedef MySqlResultList::iterator MySqlResultListIt;

class _DLL CYYMysql
{
public:
	CYYMysql();
	~CYYMysql();

	bool Initialize(const char* Hostname, unsigned int port,const char* Username, const char* Password, const char* DatabaseName,int ConnectionCount,int JobCount);

	void Start();

	void Stop();

public:

	// pool func
	void ExecuteQueryNoRet(char *query);

	bool SelectDB(CYYMySqlCon*con,char *db);

	bool Query(CYYMySqlCon*con,char*cmd,MYSQL_RES *res);

	bool Query(char*cmd,MySqlResultList *data);

	bool GetFirstRow(CYYMySqlCon*con,char*cmd,MYSQL_ROW &row);

	CYYMySqlCon * GetFreeCon();
	void ReleaseCon(CYYMySqlCon*con);

	CYYJob * GetFreeJob(char *query);
	void ReleaseJob(CYYJob*job);

protected:
private:

	CThreadPool m_ThreadPool;

	YYMySqlConList m_FreeList;
	YYMySqlConList m_BusyList;

	YYJobList	m_FreeJobList;
	YYJobList	m_BusyJobList;

	YYMYSQL::CLock	m_SqlPoolLock;
	YYMYSQL::CLock	m_jobPoolLock;
};